﻿/* $RCSFile: CrmUtil4SiteMap.cs $
 * Apache license v2 2011 by Christian Surieux
 * $Source: ?/CRMWrapper3/CrmUtil4SiteMap.cs $
 * $log$
 * Revision 6 2010/08/06 19:56:31  christian.surieux
 *   Added Log to All cs files
 */

using System;
using System.Diagnostics;
using System.Collections.Generic;
using System.Text;
using System.Net;
using System.Xml;
using System.IO;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.Configuration;
using System.Web.Services.Protocols;
using System.Globalization;

using CrmSdk.CRM4;

using AddonNice.CRMWrapper.Design;
using AddonNice.CRMWrapper.CRM4Server;
using AddonNice.CRMWrapper.CRM4Meta;

namespace AddonNice.CRMWrapper
{
    /// <summary>
    /// Toolkit to modify CRM SiteMap
    /// Add an Button
    /// Add an Area
    /// Import/Export datas
    /// </summary>
    public class CrmUtil4SiteMap
    {
                
        #region metadata management

        protected string _DataXml       =   string.Empty;
        public string DataXml           
        {
            get { return _DataXml; }
            set { _DataXml = value; }
        }
        
        protected XmlDocument _metadata =   new XmlDocument();
        
        public XmlDocument Metadata
        {
            get { return _metadata; }
            set { _metadata = value; }
        }

        #endregion metadata management

        #region properties

        CrmWrapper4 _wrapper   =   null;
        CrmWrapper4 wrapper
        {
            get
            {
                return _wrapper;
            }
        }

        string _errMsg  =   string.Empty;
        public string errMsg
        {
            get
            {
                return _errMsg;
            }
        }

        string _LCID    = System.Threading.Thread.CurrentThread.CurrentCulture.LCID.ToString();
        public string LCID
        {
            get
            {
                return _LCID;
            }
        }

        #region output/output values to set before or automatically selected 

        string _AreaName   =   string.Empty;
        public string AreaName
        {
            get
            {
                if ( _AreaName == string.Empty )
                    _AreaName =   "ADDONNICE_AREA";
                return _AreaName;
            }
            set
            {
                _AreaName  =   value;
            }
        }

        
        #endregion output/output values to set before or automatically selected 
        
        #endregion properties

        #region Ctor

        public CrmUtil4SiteMap(CrmWrapper4 wrap)
        {
            _wrapper        =   wrap;
        }

        #endregion Ctor
        
        #region Add SiteMap internal methods

        #endregion Add SiteMap internal methods

        #region Build a tree with Crm SiteMap data

        public TreeUtil BuildDetailledTree()
        {
            if ( CRMTraceSwitch.Sw.TraceVerbose )
                Trace.WriteLine( "[V]CrmUtil4SiteMap BuildDetailledTree BEG.",CRMTraceSwitch.Sw.Info);
            Metadata                =   new XmlDocument();
            _metadata.LoadXml(DataXml);
            
            string path             =   "//SiteMap/SiteMap/Area";
            XmlNodeList Areas       =   _metadata.SelectNodes(path);
            if ( CRMTraceSwitch.Sw.TraceVerbose )
                Trace.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]CrmUtil4SiteMap BuildDetailledTree areas Count: {0}",Areas.Count),CRMTraceSwitch.Sw.Info);
           
            TreeUtil RadTreeView1   =   new TreeUtil("Sitemap",NodeType.SiteMap);
            NodeUtil nd0            =   RadTreeView1.Node;
            
            NodeUtil  nd            =   null;
            foreach (XmlNode areaNode in Areas)
            {
/*
DescriptionResourceID  For internal use only. String No 
Icon Specifies a URL to an image. String No 
ID Specifies a unique identifier in ASCII. Spaces are not allowed. Valid values:a-z, A-Z, 0-9, and underscore (_) String Yes 
License Deprecated. String No 
ResourceId For internal use only String No 
ShowGroups Control whether groups of sub-areas are shown in the navigation pane. Valid values:true/false  Boolean No 
Title Deprecated Use the Titles and Title elements. String No 
Url Specifies the Microsoft Dynamics CRM for Outlook URL to render for the Outlook folder that represents the Area. 
 */
                StringBuilder sb    =   new StringBuilder();
                sb.AppendFormat("Area Id='{0}'",areaNode.Attributes["Id"].InnerText);
                NodeUtil areaNd     =   new NodeUtil(NodeType.Area);
                nd0.Nodes.Add(areaNd);
                if ( CRMTraceSwitch.Sw.TraceVerbose )
                    Trace.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]CrmUtil4SiteMap BuildDetailledTree areaNd.Text: {0}",areaNd.Text),CRMTraceSwitch.Sw.Info);
                if ( areaNode.Attributes["ShowGroups"] != null )
                    sb.AppendFormat(", ShowGroups: '{0}'",areaNode.Attributes["ShowGroups"].InnerText);
                if ( areaNode.Attributes["Icon"] != null )
                    sb.AppendFormat(", Icon: '{0}'",areaNode.Attributes["Icon"].InnerText);
                if ( areaNode.Attributes["Url"] != null )
                    sb.AppendFormat("<br />Url: '{0}'",areaNode.Attributes["Url"].InnerText);
                if ( areaNode.Attributes["DescriptionResourceID"] != null )
                    sb.AppendFormat("<br />DescriptionResourceID: '{0}'",areaNode.Attributes["DescriptionResourceID"].InnerText);
                if ( areaNode.Attributes["ResourceId"] != null )
                    sb.AppendFormat("<br />ResourceId: '{0}'",areaNode.Attributes["ResourceId"].InnerText);

                areaNd.Text             =   sb.ToString();
                
                XmlNodeList titles      =   areaNode.SelectNodes("Titles/Title");
                foreach (XmlNode titleNode in titles)
                {
                    nd  =   new NodeUtil(string.Format("Title: '{0}' - '{1}'",titleNode.Attributes["LCID"].InnerText,titleNode.Attributes["Title"].InnerText),NodeType.Title);
                    areaNd.Nodes.Add(nd);
                }

                XmlNodeList descriptions    =   areaNode.SelectNodes("Descriptions/Description");
                foreach (XmlNode descriptionNode in descriptions)
                {
                    nd  =   new NodeUtil(string.Format("Description: '{0}' - '{1}'",descriptionNode.Attributes["LCID"].InnerText,descriptionNode.Attributes["Description"].InnerText),NodeType.Description);
                    areaNd.Nodes.Add(nd);
                }
                XmlNodeList Groups      =   areaNode.SelectNodes("Group");
                foreach (XmlNode groupNode in Groups)
                {
                    /*
                    Description Deprecated. Use the Description Element.  String No 
                    DescriptionResourceID  For internal use only. String No 
                    Icon Specifies a URL to an image. String No 
                    ID Specifies a unique identifier in ASCII. Spaces are not allowed. Valid values:a-z, A-Z, 0-9, and underscore (_) String Yes 
                    IsProfile Controls whether this group represents a user selectable Profile for the Workplace.Valid values:true/false Boolean No 
                    License Deprecated. String No 
                    ResourceId For internal use only String No 
                    Title Deprecated. Use the Titles and Title elements. String No 
                    URL Specifies the URL to render for the Outlook folder that represents the Group in Microsoft Dynamics CRM for Outlook. String No 
                    */
                    if ( CRMTraceSwitch.Sw.TraceVerbose )
                        Trace.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]CrmUtil4SiteMap BuildDetailledTree groupNode: {0}",groupNode.Attributes["Id"].InnerText),CRMTraceSwitch.Sw.Info);
                    sb                  =   new StringBuilder();
                    NodeUtil gnd        =   new NodeUtil(NodeType.Group);
                    areaNd.Nodes.Add(gnd);
                    sb.AppendFormat("Group Id='{0}'",groupNode.Attributes["Id"].InnerText);
                    if ( groupNode.Attributes["IsProfile"] != null )
                        sb.AppendFormat(", IsProfile: {0}",groupNode.Attributes["IsProfile"].InnerText);
                    if ( groupNode.Attributes["Icon"] != null )
                        sb.AppendFormat(", Icon: '{0}'",groupNode.Attributes["Icon"].InnerText);
                    if ( groupNode.Attributes["Url"] != null )
                        sb.AppendFormat("<br />Url: {0}",groupNode.Attributes["Url"].InnerText);
                    if ( groupNode.Attributes["DescriptionResourceID"] != null )
                        sb.AppendFormat("<br />DescriptionResourceID: '{0}'",groupNode.Attributes["DescriptionResourceID"].InnerText);
                    if ( groupNode.Attributes["ResourceId"] != null )
                        sb.AppendFormat("<br />ResourceId: '{0}'",groupNode.Attributes["ResourceId"].InnerText);
                    gnd.Text            =   sb.ToString();
                    titles              =   groupNode.SelectNodes("Titles/Title");
                    foreach (XmlNode titleNode in titles)
                    {
                        nd  =   new NodeUtil(string.Format("Title: '{0}' - '{1}'",titleNode.Attributes["LCID"].InnerText,titleNode.Attributes["Title"].InnerText),NodeType.Title);
                        gnd.Nodes.Add(nd);
                    }
                    
                    descriptions    =   groupNode.SelectNodes("Descriptions/Description");
                    foreach (XmlNode descriptionNode in descriptions)
                    {
                        nd  =   new NodeUtil(string.Format("Description: '{0}' - '{1}'",descriptionNode.Attributes["LCID"].InnerText,descriptionNode.Attributes["Description"].InnerText),NodeType.Description);
                        gnd.Nodes.Add(nd);
                    }
                    XmlNodeList subAreas    =   groupNode.SelectNodes("SubArea");
                    foreach (XmlNode subAreaNode in subAreas)
                    {
/*
AvailableOffline Controls whether SubArea is available offline. Valid values:true/false  Boolean No 
Client Specifies the type of client Default: All  Valid values:
    All
    Outlook
    OutlookLaptopClient
    OutlookWorkstationClient
    Web
    Multiple values can be used as long as they are separated by a comma and do not contain spaces. String No 
Description Deprecated. Use the Description Element. String No 
DescriptionResourceID  For internal use only String No 
Entity Specifies the schema name for the entity String No 
Icon Specifies the icon to display. String No 
ID Specifies a unique identifier in ASCII, with no spaces. Valid values:a-z, A-Z, 0-9, and underscore (_) String Yes 
License Deprecated String   
PassParams Specifies whether information about the organization and language context are passed to the URL. See Passing Parameters to a URL Using SiteMap. 
Valid values:
    0 = don't pass parameters [default]
    1 = pass parameters
    Boolean No 
OutlookShortcutIcon Specifies the icon to display in Microsoft Dynamics CRM for Microsoft Office Outlook. String No 
ResourceId For internal use only String No 
Title Deprecated. Use the Titles and Title elements. String No 
URL Specifies the URL to render for this SubArea. String No 
 */
                        if ( CRMTraceSwitch.Sw.TraceVerbose )
                            Trace.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]CrmUtil4SiteMap BuildDetailledTree subAreaNode: {0}",subAreaNode.Attributes["Id"].InnerText),CRMTraceSwitch.Sw.Info);
                        NodeUtil arnd       =   new NodeUtil(NodeType.SubArea);
                        gnd.Nodes.Add(arnd);
                        sb                  =   new StringBuilder();
                        sb.AppendFormat("SubArea Id='{0}'",subAreaNode.Attributes["Id"].InnerText);
                        if ( subAreaNode.Attributes["AvailableOffline"] != null )
                            sb.AppendFormat("AvailableOffline: '{0}'",subAreaNode.Attributes["AvailableOffline"].InnerText);
                        if ( subAreaNode.Attributes["Client"] != null )
                            sb.AppendFormat(", Client: '{0}'",subAreaNode.Attributes["Client"].InnerText);
                        if ( subAreaNode.Attributes["Entity"] != null )
                            sb.AppendFormat(", Entity: '{0}'",subAreaNode.Attributes["Entity"].InnerText);
                        if ( subAreaNode.Attributes["Icon"] != null )
                            sb.AppendFormat(", Icon: '{0}'",subAreaNode.Attributes["Icon"].InnerText);
                        if ( subAreaNode.Attributes["PassParams"] != null )
                            sb.AppendFormat(", PassParams: '{0}'",subAreaNode.Attributes["PassParams"].InnerText);
                        if ( subAreaNode.Attributes["OutlookShortcutIcon"] != null )
                            sb.AppendFormat(", OutlookShortcutIcon: '{0}'",subAreaNode.Attributes["OutlookShortcutIcon"].InnerText);
                        if ( subAreaNode.Attributes["Url"] != null )
                            sb.AppendFormat("<br />Url: '{0}'",subAreaNode.Attributes["Url"].InnerText);
                        if ( subAreaNode.Attributes["DescriptionResourceID"] != null )
                            sb.AppendFormat("<br />DescriptionResourceID: '{0}'",subAreaNode.Attributes["DescriptionResourceID"].InnerText);
                        if ( subAreaNode.Attributes["ResourceId"] != null )
                            sb.AppendFormat("<br />ResourceId: '{0}'",subAreaNode.Attributes["ResourceId"].InnerText);
                        arnd.Text           =   sb.ToString();
                        titles              =   subAreaNode.SelectNodes("Titles/Title");
                        foreach (XmlNode titleNode in titles)
                        {
                            nd          =   new NodeUtil(string.Format("Title: '{0}' - '{1}'",titleNode.Attributes["LCID"].InnerText,titleNode.Attributes["Title"].InnerText),NodeType.Title);
                            arnd.Nodes.Add(nd);
                        }
                        
                        descriptions        =   subAreaNode.SelectNodes("Descriptions/Description");
                        foreach (XmlNode descriptionNode in descriptions)
                        {
                            nd  =   new NodeUtil(string.Format("Description: '{0}' - '{1}'",descriptionNode.Attributes["LCID"].InnerText,descriptionNode.Attributes["Description"].InnerText),NodeType.Description);
                            arnd.Nodes.Add(nd);
                        }
                        XmlNodeList privileges    =   subAreaNode.SelectNodes("Privilege");
                        foreach (XmlNode privilegeNode in privileges)
                        {
                            sb                  =   new StringBuilder();
                            nd                  =   new NodeUtil(NodeType.Privilege);
                            sb.AppendFormat("Privilege: '{0}'",privilegeNode.Attributes["Privilege"].InnerText);
                            if ( privilegeNode.Attributes["Entity"] != null )
                                sb.AppendFormat(", Entity: '{0}'",privilegeNode.Attributes["Entity"].InnerText);
                            nd.Text             =   sb.ToString();
                            arnd.Nodes.Add(nd);
                        }
                    }
                }
            }
            return RadTreeView1;
        }

        #endregion Build a tree with Crm SiteMap data

        #region public methods

        /// <summary>
        /// Export SiteMap from Crm into DataXml property of thos object
        /// </summary>
        /// <returns></returns>
        public string ExportXml()
        {
            if ( CRMTraceSwitch.Sw.TraceVerbose )
                Trace.WriteLine("[V]CrmUtil4SiteMap ExportXml BEG .",CRMTraceSwitch.Sw.Info);
            ImportExportXml ImportExportData    =   new ImportExportXml(ImportExportType.sitemap);
            bool ret                            =   ImportExportData.Export(wrapper);
            if ( ret)
            {
                DataXml                         =   ImportExportData.DataXml;
            }
            else _errMsg                         =   ImportExportData.strErr;
            if ( CRMTraceSwitch.Sw.TraceVerbose )
                Trace.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]CrmUtil4SiteMap ExportXml END ret: {0}", ret),CRMTraceSwitch.Sw.Info);
            return DataXml;
        }

        /// <summary>
        /// Import into Crm SiteMap contained in DataXml property
        /// </summary>
        public string ImportXml(bool publish)
        {
            if ( CRMTraceSwitch.Sw.TraceVerbose )
                Trace.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]CrmUtil4SiteMap ImportXml BEG publish: {0}",publish),CRMTraceSwitch.Sw.Info);
            ImportExportXml ImportExportData    =   new ImportExportXml(ImportExportType.sitemap,DataXml);
            bool ret                            =   ImportExportData.Import(wrapper,publish);
            if ( !ret )
                _errMsg                         =   ImportExportData.strErr;

            if ( CRMTraceSwitch.Sw.TraceVerbose )
                Trace.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]CrmUtil4SiteMap ImportXml END ret: {0}", ret),CRMTraceSwitch.Sw.Info);
            return DataXml;
        }

        /// <summary>
        /// Do an export/update/import for SiteMap
        /// </summary>
        public bool UpdateSiteMap(string newSiteMap,bool publish)
        {
            if ( CRMTraceSwitch.Sw.TraceVerbose )
                Trace.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]CrmUtil4SiteMap UpdateSiteMap BEG publish: {0}",publish),CRMTraceSwitch.Sw.Info);
            bool ret                                =   false;
            try
            {
                DataXml                             =   newSiteMap;
                ImportExportXml ImportExportData    =   new ImportExportXml(ImportExportType.sitemap,DataXml);
                ret                                 =   ImportExportData.Import(wrapper,publish);
                if ( !ret )
                    _errMsg                         =   ImportExportData.strErr;
            }
			catch (Exception ex)
			{
                if ( CRMTraceSwitch.Sw.TraceError )
                    Trace.WriteLine( string.Format(CultureInfo.InvariantCulture,"[E]CrmUtil4SiteMap UpdateSiteMap ex: {0}",ex),CRMTraceSwitch.Sw.Info);
                throw;
			}
             if ( CRMTraceSwitch.Sw.TraceVerbose )
                Trace.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]CrmUtil4SiteMap UpdateSiteMap END ret: {0}", ret),CRMTraceSwitch.Sw.Info);
            return ret;
        }

        #region Sequential operations

        public ImportExportXml Init()
        {
            if ( CRMTraceSwitch.Sw.TraceVerbose )
                Trace.WriteLine( "[V]CrmUtil4SiteMap Init BEG.",CRMTraceSwitch.Sw.Info);
            bool ret                                =   false;
            ImportExportXml ImportExportData        =   null;
            try
            {
                ImportExportData                    =   new ImportExportXml(ImportExportType.sitemap);
                ret                                 =   ImportExportData.Export(wrapper);
                if ( ret )
                {
                    DataXml                         =   ImportExportData.DataXml;
                    Metadata                        =   new XmlDocument();
                    _metadata.LoadXml(DataXml);
                }
                else _errMsg                         =   ImportExportData.strErr;
            }
			catch (Exception ex)
			{
                if ( CRMTraceSwitch.Sw.TraceError )
                    Trace.WriteLine( string.Format(CultureInfo.InvariantCulture,"[E]CrmUtil4SiteMap Init ex: {0}",ex),CRMTraceSwitch.Sw.Info);
                throw;
			}
             if ( CRMTraceSwitch.Sw.TraceVerbose )
                Trace.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]CrmUtil4SiteMap Init END ret: {0}", ret),CRMTraceSwitch.Sw.Info);
            if ( ret )
                return ImportExportData;
            return null;
        }

        public bool Save(ImportExportXml ImportExportData,bool publish)
        {
            bool ret    =   false;
            try
            {
                DataXml                         =   _metadata.InnerXml;
                if ( CRMTraceSwitch.Sw.TraceVerbose )
                    Trace.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]CrmUtil4SiteMap Save DataXml: {0}, publish: {1}", DataXml,publish),CRMTraceSwitch.Sw.Info);
                ImportExportData.DataXml        =   DataXml;
                ret                             =   ImportExportData.Import(wrapper,publish);
                if ( !ret )
                    _errMsg                     =   ImportExportData.strErr;
            }
			catch (Exception ex)
			{
                if ( CRMTraceSwitch.Sw.TraceError )
                    Trace.WriteLine( string.Format(CultureInfo.InvariantCulture,"[E]CrmUtil4SiteMap Save ex: {0}",ex),CRMTraceSwitch.Sw.Info);
                throw;
			}
             if ( CRMTraceSwitch.Sw.TraceVerbose )
                Trace.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]CrmUtil4SiteMap Save END ret: {0}", ret),CRMTraceSwitch.Sw.Info);
            return ret;
        }

        public bool AddNewAreaNoImport(string nextAreaId,string areaXml,string areaId)
        {
            if ( CRMTraceSwitch.Sw.TraceVerbose )
                Trace.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]CrmUtil4SiteMap AddNewAreaNoImport BEG NextAreaId: '{0}', areaXml: {1}", nextAreaId, areaXml),CRMTraceSwitch.Sw.Info);
            try
            {
                string path                     =   "//SiteMap/SiteMap";
                XmlNode SiteMapNd               =   _metadata.SelectSingleNode(path);
                if ( CRMTraceSwitch.Sw.TraceVerbose )
                    Trace.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]CrmUtil4SiteMap AddNewArea SiteMapNd null: {0}", SiteMapNd == null ),CRMTraceSwitch.Sw.Info);
                if ( SiteMapNd == null )
                {
                    if ( CRMTraceSwitch.Sw.TraceVerbose || InstallTraceSwitchW.Sw.TraceVerbose )
                        Trace.WriteLine("[V]CrmUtil4SiteMap AddNewAreaNoImport END false.",(CRMTraceSwitch.Sw.TraceVerbose ) ?CRMTraceSwitch.Sw.Info:InstallTraceSwitchW.Sw.Info);
                    return false;
                }
                // Test for existing area with same Id
                path                            =   string.Format("Area[@Id='{0}']", areaId);
                XmlNode EAreaNd                 =   SiteMapNd.SelectSingleNode(path);
                bool found                      =   (EAreaNd != null);
                if ( CRMTraceSwitch.Sw.TraceVerbose )
                    Trace.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]CrmUtil4SiteMap AddNewAreaNoImport Existing AreaId: {0}, found: {1}",areaId,found),CRMTraceSwitch.Sw.Info);
                if ( found )
                {
                    if ( CRMTraceSwitch.Sw.TraceVerbose || InstallTraceSwitchW.Sw.TraceVerbose )
                        Trace.WriteLine("[V]CrmUtil4SiteMap AddNewAreaNoImport END false.",(CRMTraceSwitch.Sw.TraceVerbose ) ?CRMTraceSwitch.Sw.Info:InstallTraceSwitchW.Sw.Info);
                    return false;
                }
                XmlDocumentFragment newArea     =   _metadata.CreateDocumentFragment();
                newArea.InnerXml                =   areaXml;
                if (string.IsNullOrEmpty(nextAreaId))
                    SiteMapNd.AppendChild(newArea);
                else
                {
                    path                        =   string.Format("Area[@Id='{0}']", nextAreaId);
                    XmlNode AreaNd              =   SiteMapNd.SelectSingleNode(path);
                    if ( CRMTraceSwitch.Sw.TraceVerbose )
                        Trace.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]CrmUtil4SiteMap AddNewAreaNoImport AreaNd null: {0}", AreaNd == null ),CRMTraceSwitch.Sw.Info);
                    SiteMapNd.InsertAfter(newArea, AreaNd);
                }
            }
			catch (Exception ex)
			{
                if ( CRMTraceSwitch.Sw.TraceError )
                    Trace.WriteLine( string.Format(CultureInfo.InvariantCulture,"[E]CrmUtil4SiteMap AddNewAreaNoImport ex: {0}",ex),CRMTraceSwitch.Sw.Info);
                throw;
			}
             if ( CRMTraceSwitch.Sw.TraceVerbose )
                Trace.WriteLine( "[V]CrmUtil4SiteMap AddNewAreaNoImport END true.",CRMTraceSwitch.Sw.Info);
            return true;
        }

        public bool AddNewGroupNoImport(string AreaId,string nextGroupId,string groupXml,string groupId)
        {
            if ( CRMTraceSwitch.Sw.TraceVerbose )
                Trace.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]CrmUtil4SiteMap AddNewGroupNoImport BEG AreaId: {0}, nextGroupId: '{1}', groupXml: {2}", AreaId,nextGroupId, groupXml),CRMTraceSwitch.Sw.Info);
            try
            {
                string path                     =   string.Format("//SiteMap/SiteMap/Area[@Id='{0}']",AreaId);
                XmlNode AreaNd                  =   _metadata.SelectSingleNode(path);
                if ( CRMTraceSwitch.Sw.TraceVerbose )
                    Trace.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]CrmUtil4SiteMap AddNewGroupNoImport AreaNd null: {0}", AreaNd == null ),CRMTraceSwitch.Sw.Info);
                if ( AreaNd == null )
                {
                    if ( CRMTraceSwitch.Sw.TraceVerbose || InstallTraceSwitchW.Sw.TraceVerbose )
                        Trace.WriteLine("[V]CrmUtil4SiteMap AddNewGroupNoImport END false.",(CRMTraceSwitch.Sw.TraceVerbose ) ?CRMTraceSwitch.Sw.Info:InstallTraceSwitchW.Sw.Info);
                    return false;
                }
                // Test for existing group with same Id
                path                            =   string.Format("Group[@Id='{0}']", groupId);
                XmlNode EGroupNd                =   AreaNd.SelectSingleNode(path);
                bool found                      =   (EGroupNd != null);
                if ( CRMTraceSwitch.Sw.TraceVerbose )
                    Trace.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]CrmUtil4SiteMap AddNewGroupNoImport Existing GroupId: {0}, found: {1}",groupId,found),CRMTraceSwitch.Sw.Info);
                if ( found )
                {
                    if ( CRMTraceSwitch.Sw.TraceVerbose || InstallTraceSwitchW.Sw.TraceVerbose )
                        Trace.WriteLine("[V]CrmUtil4SiteMap AddNewGroupNoImport END false.",(CRMTraceSwitch.Sw.TraceVerbose ) ?CRMTraceSwitch.Sw.Info:InstallTraceSwitchW.Sw.Info);
                    return false;
                }
                XmlDocumentFragment newGroup    =   _metadata.CreateDocumentFragment();
                newGroup.InnerXml               =   groupXml;
                if (string.IsNullOrEmpty(nextGroupId))
                    AreaNd.AppendChild(newGroup);
                else
                {
                    path                        =   string.Format("Group[@Id='{0}']", nextGroupId);
                    XmlNode GroupNd             =   AreaNd.SelectSingleNode(path);
                    if ( CRMTraceSwitch.Sw.TraceVerbose )
                        Trace.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]CrmUtil4SiteMap AddNewGroupNoImport GroupNd null: {0}", GroupNd == null ),CRMTraceSwitch.Sw.Info);
                    AreaNd.InsertAfter(newGroup, GroupNd);
                }
            }
			catch (Exception ex)
			{
                if ( CRMTraceSwitch.Sw.TraceError )
                    Trace.WriteLine( string.Format(CultureInfo.InvariantCulture,"[E]CrmUtil4SiteMap AddNewGroupNoImport ex: {0}",ex),CRMTraceSwitch.Sw.Info);
                throw;
			}
             if ( CRMTraceSwitch.Sw.TraceVerbose )
                Trace.WriteLine( "[V]CrmUtil4SiteMap AddNewGroupNoImport END true.",CRMTraceSwitch.Sw.Info);
            return true;
        }

        public bool AddNewSubAreaNoImport(string AreaId,string GroupId,string nextSubAreaId,string subAreaXml,string subAreaId)
        {
            if ( CRMTraceSwitch.Sw.TraceVerbose )
                Trace.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]CrmUtil4SiteMap AddNewSubAreaNoImport BEG AreaId: {0}, GroupId: {1}, nextSubAreaId: {2}, subAreaXml: {3}", 
                    new object[]{AreaId,GroupId,nextSubAreaId, subAreaXml}),CRMTraceSwitch.Sw.Info);
            try
            {
                string path                     =   string.Format("//SiteMap/SiteMap/Area[@Id='{0}']/Group[@Id='{1}']",AreaId,GroupId);
                XmlNode GroupNd                 =   _metadata.SelectSingleNode(path);
                if ( CRMTraceSwitch.Sw.TraceVerbose )
                    Trace.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]CrmUtil4SiteMap AddNewSubArea GroupNd null: {0}", GroupNd == null ),CRMTraceSwitch.Sw.Info);
                if ( GroupNd == null )
                {
                    if ( CRMTraceSwitch.Sw.TraceVerbose || InstallTraceSwitchW.Sw.TraceVerbose )
                        Trace.WriteLine("[V]CrmUtil4SiteMap AddNewSubAreaNoImport END false.",(CRMTraceSwitch.Sw.TraceVerbose ) ?CRMTraceSwitch.Sw.Info:InstallTraceSwitchW.Sw.Info);
                    return false;
                }
                // Test for existing subArea with same Id
                path                            =   string.Format("SubArea[@Id='{0}']", subAreaId);
                XmlNode EsubAreaNd              =   GroupNd.SelectSingleNode(path);
                bool found                      =   (EsubAreaNd != null);
                if ( CRMTraceSwitch.Sw.TraceVerbose )
                    Trace.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]CrmUtil4SiteMap AddNewSubAreaNoImport Existing subAreaId: {0}, found: {1}",subAreaId,found),CRMTraceSwitch.Sw.Info);
                if ( found )
                {
                    if ( CRMTraceSwitch.Sw.TraceVerbose || InstallTraceSwitchW.Sw.TraceVerbose )
                        Trace.WriteLine("[V]CrmUtil4SiteMap AddNewSubAreaNoImport END false.",(CRMTraceSwitch.Sw.TraceVerbose ) ?CRMTraceSwitch.Sw.Info:InstallTraceSwitchW.Sw.Info);
                    return false;
                }
                XmlDocumentFragment newSubArea  =   _metadata.CreateDocumentFragment();
                newSubArea.InnerXml             =   subAreaXml;
                if (string.IsNullOrEmpty(nextSubAreaId))
                    GroupNd.AppendChild(newSubArea);
                else
                {
                    path                        =   string.Format("SubArea[@Id='{0}']", nextSubAreaId);
                    XmlNode subAreaNd           =   GroupNd.SelectSingleNode(path);
                    if ( CRMTraceSwitch.Sw.TraceVerbose )
                        Trace.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]CrmUtil4SiteMap AddNewSubAreaNoImport subAreaNd null: {0}", subAreaNd == null ),CRMTraceSwitch.Sw.Info);
                    if ( subAreaNd == null )
                         GroupNd.AppendChild(newSubArea);
                    else GroupNd.InsertAfter(newSubArea, subAreaNd);
                }
            }
			catch (Exception ex)
			{
                if ( CRMTraceSwitch.Sw.TraceError )
                    Trace.WriteLine( string.Format(CultureInfo.InvariantCulture,"[E]CrmUtil4SiteMap AddNewSubAreaNoImport ex: {0}",ex),CRMTraceSwitch.Sw.Info);
                throw;
			}
            if ( CRMTraceSwitch.Sw.TraceVerbose )
                Trace.WriteLine( "[V]CrmUtil4SiteMap AddNewSubAreaNoImport END true.",CRMTraceSwitch.Sw.Info);
            return true;
        }

        #endregion Sequential operations

        #region Ponctual operations

        /// <summary>
        /// Do a one shoot export/ Add Area / import operation on CRM
        /// </summary>
        public bool AddNewArea(string nextAreaId,string areaXml,string areaId,bool publish)
        {
            if ( CRMTraceSwitch.Sw.TraceVerbose )
                Trace.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]CrmUtil4SiteMap AddNewArea BEG NextAreaId: '{0}', areaXml: {1}", nextAreaId, areaXml),CRMTraceSwitch.Sw.Info);
            bool ret                                =   false;
            try
            {
                ImportExportXml ImportExportData    =   new ImportExportXml(ImportExportType.sitemap);
                ret                                 =   ImportExportData.Export(wrapper);
                if ( ret )
                {
                    DataXml                         =   ImportExportData.DataXml;
                    Metadata                        =   new XmlDocument();
                    _metadata.LoadXml(DataXml);
                    string path                     =   "//SiteMap/SiteMap";
                    XmlNode SiteMapNd               =   _metadata.SelectSingleNode(path);
                    if ( CRMTraceSwitch.Sw.TraceVerbose )
                        Trace.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]CrmUtil4SiteMap AddNewArea SiteMapNd null: {0}", SiteMapNd == null ),CRMTraceSwitch.Sw.Info);
                    // Test for existing area with same Id
                    path                            =   string.Format("Area[@Id='{0}']", areaId);
                    XmlNode EAreaNd                 =   SiteMapNd.SelectSingleNode(path);
                    bool found                      =   (EAreaNd != null);
                    if ( CRMTraceSwitch.Sw.TraceVerbose )
                        Trace.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]CrmUtil4SiteMap AddNewArea Existing AreaId: {0}, found: {1}",areaId,found),CRMTraceSwitch.Sw.Info);
                    if ( found )
                        return true;
                    XmlDocumentFragment newArea     =   _metadata.CreateDocumentFragment();
                    newArea.InnerXml                =   areaXml;
                    if (string.IsNullOrEmpty(nextAreaId))
                        SiteMapNd.AppendChild(newArea);
                    else
                    {
                        path                        =   string.Format("Area[@Id='{0}']", nextAreaId);
                        XmlNode AreaNd              =   SiteMapNd.SelectSingleNode(path);
                        if ( CRMTraceSwitch.Sw.TraceVerbose )
                            Trace.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]CrmUtil4SiteMap AddNewArea AreaNd null: {0}", AreaNd == null ),CRMTraceSwitch.Sw.Info);
                        SiteMapNd.InsertAfter(newArea, AreaNd);
                    }
                }
                if (ret )
                {
                    DataXml                         =   _metadata.InnerXml;
                    if ( CRMTraceSwitch.Sw.TraceVerbose )
                        Trace.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]CrmUtil4SiteMap AddNewArea DataXml: {0}", DataXml),CRMTraceSwitch.Sw.Info);
                    ImportExportData.DataXml        =   DataXml;
                    ret                             =   ImportExportData.Import(wrapper,publish);
                }
                if ( !ret )
                    _errMsg                         =   ImportExportData.strErr;
            }
			catch (Exception ex)
			{
                if ( CRMTraceSwitch.Sw.TraceError )
                    Trace.WriteLine( string.Format(CultureInfo.InvariantCulture,"[E]CrmUtil4SiteMap AddNewArea ex: {0}",ex),CRMTraceSwitch.Sw.Info);
                throw;
			}
             if ( CRMTraceSwitch.Sw.TraceVerbose )
                Trace.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]CrmUtil4SiteMap AddNewArea END ret: {0}", ret),CRMTraceSwitch.Sw.Info);
            return ret;
        }
        

        /// <summary>
        /// Do a one shoot export/ Add Group / import operation on CRM
        /// </summary>
        public bool AddNewGroup(string AreaId,string nextGroupId,string groupXml,string groupId,bool publish)
        {
            if ( CRMTraceSwitch.Sw.TraceVerbose )
                Trace.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]CrmUtil4SiteMap AddNewGroup BEG AreaId: {0}, nextGroupId: '{1}', groupXml: {2}", AreaId,nextGroupId, groupXml),CRMTraceSwitch.Sw.Info);
            bool ret                                =   false;
            try
            {
                ImportExportXml ImportExportData    =   new ImportExportXml(ImportExportType.sitemap);
                ret                                 =   ImportExportData.Export(wrapper);
                if ( ret )
                {
                    DataXml                         =   ImportExportData.DataXml;
                    Metadata                        =   new XmlDocument();
                    _metadata.LoadXml(DataXml);
                    string path                     =   string.Format("//SiteMap/SiteMap/Area[@Id='{0}']",AreaId);
                    XmlNode AreaNd                  =   _metadata.SelectSingleNode(path);
                    if ( CRMTraceSwitch.Sw.TraceVerbose )
                        Trace.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]CrmUtil4SiteMap AddNewGroup AreaNd null: {0}", AreaNd == null ),CRMTraceSwitch.Sw.Info);
                    // Test for existing group with same Id
                    path                            =   string.Format("Group[@Id='{0}']", groupId);
                    XmlNode EGroupNd                =   AreaNd.SelectSingleNode(path);
                    bool found                      =   (EGroupNd != null);
                    if ( CRMTraceSwitch.Sw.TraceVerbose )
                        Trace.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]CrmUtil4SiteMap AddNewGroup Existing GroupId: {0}, found: {1}",groupId,found),CRMTraceSwitch.Sw.Info);
                    if ( found )
                        return true;
                    XmlDocumentFragment newGroup    =   _metadata.CreateDocumentFragment();
                    newGroup.InnerXml               =   groupXml;
                    if (string.IsNullOrEmpty(nextGroupId))
                        AreaNd.AppendChild(newGroup);
                    else
                    {
                        path                        =   string.Format("Group[@Id='{0}']", nextGroupId);
                        XmlNode GroupNd             =   AreaNd.SelectSingleNode(path);
                        if ( CRMTraceSwitch.Sw.TraceVerbose )
                            Trace.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]CrmUtil4SiteMap AddNewGroup GroupNd null: {0}", GroupNd == null ),CRMTraceSwitch.Sw.Info);
                        AreaNd.InsertAfter(newGroup, GroupNd);
                    }
                }
                if (ret )
                {
                    DataXml                         =   _metadata.InnerXml;
                    if ( CRMTraceSwitch.Sw.TraceVerbose )
                        Trace.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]CrmUtil4SiteMap AddNewGroup DataXml: {0}", DataXml),CRMTraceSwitch.Sw.Info);
                    ImportExportData.DataXml        =   DataXml;
                    ret                             =   ImportExportData.Import(wrapper,publish);
                }
                if ( !ret )
                    _errMsg                         =   ImportExportData.strErr;
            }
			catch (Exception ex)
			{
                if ( CRMTraceSwitch.Sw.TraceError )
                    Trace.WriteLine( string.Format(CultureInfo.InvariantCulture,"[E]CrmUtil4SiteMap AddNewGroup ex: {0}",ex),CRMTraceSwitch.Sw.Info);
                throw;
			}
             if ( CRMTraceSwitch.Sw.TraceVerbose )
                Trace.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]CrmUtil4SiteMap AddNewGroup END ret: {0}", ret),CRMTraceSwitch.Sw.Info);
            return ret;
        }

        public static string NewArea(string id,string langCode,string Title,string Description,string iconurl)
        {
            string str      =   string.Format("<Area Id=\"{0}\" Icon='{1}'><Titles><Title LCID=\"{2}\" Title=\"{3}\" /></Titles><Descriptions><Description LCID=\"{2}\" Description=\"{4}\"/></Descriptions></Area>",
                new object[]{id,iconurl,langCode,Title,Description});
            if (InstallTraceSwitchW.Sw.TraceVerbose)
                Trace.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]CrmInstaller NewArea xml: {0}",str),InstallTraceSwitchW.Sw.Info);
            return str;
        }

        /// <summary>
        /// IsProfile shoumld be true only for groups in the Workplace area
        /// </summary>
        public static string NewGroup(string id,string langCode,string Title,string Description,bool isProfile)
        {
            string str  =   (isProfile) ? string.Format("<Group Id=\"{0}\" IsProfile=\"true\" ><Titles><Title LCID=\"{1}\" Title=\"{2}\" /></Titles><Descriptions><Description LCID=\"{1}\" Description=\"{3}\"/></Descriptions></Group>",
                                                new object[]{id,langCode,Title,Description})
                                        : string.Format("<Group Id=\"{0}\" ><Titles><Title LCID=\"{1}\" Title=\"{2}\" /></Titles><Descriptions><Description LCID=\"{1}\" Description=\"{3}\"/></Descriptions></Group>",
                                                new object[]{id,langCode,Title,Description});
            if (InstallTraceSwitchW.Sw.TraceVerbose)
                Trace.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]CrmInstaller NewGroup xml: {0}",str),InstallTraceSwitchW.Sw.Info);
            return str;
        }

        public static string NewSubArea(string id,int PassParam,string url,string langCode,string Title,bool AvailableOffline,string Client)
        {
            string str  =   string.Format( "<SubArea Id=\"{0}\" PassParams=\"{1}\" Url=\"{2}\" AvailableOffline=\"{3}\" Client=\"{4}\" ><Titles><Title LCID=\"{5}\" Title=\"{6}\" /></Titles></SubArea>",
                new object[]{id,PassParam,url,AvailableOffline ? "true":"false" ,(string.IsNullOrEmpty(Client)) ? "Web":Client,langCode,Title});
            if (InstallTraceSwitchW.Sw.TraceVerbose)
                Trace.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]CrmInstaller NewSubArea : {0}",str),InstallTraceSwitchW.Sw.Info);
            return str;
        }

        public static string NewSubAreaWithReadPrivileges(string id,int PassParam,string url,string langCode,string Title,bool AvailableOffline,List<string> ReadPrivileges,string Client)
        {
            StringBuilder sb    =   new StringBuilder();
            sb.AppendFormat( "<SubArea Id=\"{0}\" PassParams=\"{1}\" Url=\"{2}\" AvailableOffline=\"{3}\" Client=\"{4}\" ><Titles><Title LCID=\"{5}\" Title=\"{6}\" /></Titles>",
                new object[]{id,PassParam,url,AvailableOffline ? "true":"false" ,(string.IsNullOrEmpty(Client)) ? "Web":Client,langCode,Title});
            foreach(string ent in ReadPrivileges )
                sb.AppendFormat("<Privilege Entity=\"{0}\" Privilege=\"Read\" />",ent);
            sb.Append("</SubArea>");
            string str          =   sb.ToString();
            if (CRMTraceSwitch.Sw.TraceVerbose)
                Trace.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]CrmUtil4SiteMap NewSubAreaWithReadPrivileges xml: '{0}'",str),CRMTraceSwitch.Sw.Info);
            return str;
        }              
        
        /// <summary>
        /// Client Specifies the type of client 
        /// Default: All 
        /// Valid values:All,Outlook,OutlookLaptopClient,OutlookWorkstationClient,Web
        /// Multiple values can be used as long as they are separated by a comma and do not contain spaces. See Remarks.
        /// </summary>
        public static string NewEntitySubArea(string id,string wentity,bool AvailableOffline,string Client)
        {
            string str  =   string.Format( "<SubArea Id=\"{0}\" Entity=\"{1}\"  AvailableOffline=\"{2}\" Client=\"{3}\" />",
                new object[]{id,wentity,AvailableOffline ? "true":"false",(string.IsNullOrEmpty(Client)) ? "Web":Client});
            if (CRMTraceSwitch.Sw.TraceVerbose)
                Trace.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]CrmUtil4SiteMap NewEntitySubArea xml: '{0}'",str),CRMTraceSwitch.Sw.Info);
            return str;
        }

        public static string NewEntitySubAreaWithReadPrivileges(string id,string wentity,bool AvailableOffline,List<string> ReadPrivileges,string Client)
        {
            StringBuilder sb    =   new StringBuilder();
            sb.AppendFormat( "<SubArea Id=\"{0}\" Entity=\"{1}\"  AvailableOffline=\"{2}\" Client=\"{3}\" >",
                new object[]{id,wentity,AvailableOffline ? "true":"false",(string.IsNullOrEmpty(Client)) ? "Web":Client});
            foreach(string ent in ReadPrivileges )
                sb.AppendFormat("<Privilege Entity=\"{0}\" Privilege=\"Read\" />",ent);
            sb.Append("</SubArea>");
            string str          =   sb.ToString();
            if (CRMTraceSwitch.Sw.TraceVerbose)
                Trace.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]CrmUtil4SiteMap NewEntitySubAreaWithReadPrivileges xml: '{0}'",str),CRMTraceSwitch.Sw.Info);
            return str;
        }              


        /// <summary>
        /// Do a one shoot export/ Add Sub Area / import operation on CRM
        /// </summary>
        public bool AddNewSubArea(string AreaId,string GroupId,string nextSubAreaId,string subAreaXml,string subAreaId,bool publish)
        {
            if ( CRMTraceSwitch.Sw.TraceVerbose )
                Trace.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]CrmUtil4SiteMap AddNewSubArea BEG AreaId: {0}, GroupId: {1}, nextSubAreaId: {2}, subAreaXml: {3}", 
                    new object[]{AreaId,GroupId,nextSubAreaId, subAreaXml}),CRMTraceSwitch.Sw.Info);
            bool ret                                =   false;
            try
            {
                ImportExportXml ImportExportData    =   new ImportExportXml(ImportExportType.sitemap);
                ret                                 =   ImportExportData.Export(wrapper);
                if ( ret )
                {
                    DataXml                         =   ImportExportData.DataXml;
                    Metadata                        =   new XmlDocument();
                    _metadata.LoadXml(DataXml);
                    string path                     =   string.Format("//SiteMap/SiteMap/Area[@Id='{0}']/Group[@Id='{1}']",AreaId,GroupId);
                    XmlNode GroupNd                 =   _metadata.SelectSingleNode(path);
                    if ( CRMTraceSwitch.Sw.TraceVerbose )
                        Trace.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]CrmUtil4SiteMap AddNewSubArea GroupNd null: {0}", GroupNd == null ),CRMTraceSwitch.Sw.Info);
                    // Test for existing subArea with same Id
                    path                            =   string.Format("SubArea[@Id='{0}']", subAreaId);
                    XmlNode EsubAreaNd              =   GroupNd.SelectSingleNode(path);
                    bool found                      =   (EsubAreaNd != null);
                    if ( CRMTraceSwitch.Sw.TraceVerbose )
                        Trace.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]CrmUtil4SiteMap Existing subAreaId: {0}, found: {1}",subAreaId,found),CRMTraceSwitch.Sw.Info);
                    if ( found )
                        return true;
                    XmlDocumentFragment newSubArea  =   _metadata.CreateDocumentFragment();
                    newSubArea.InnerXml             =   subAreaXml;
                    if (string.IsNullOrEmpty(nextSubAreaId))
                        GroupNd.AppendChild(newSubArea);
                    else
                    {
                        path                        =   string.Format("SubArea[@Id='{0}']", nextSubAreaId);
                        XmlNode subAreaNd           =   GroupNd.SelectSingleNode(path);
                        if ( CRMTraceSwitch.Sw.TraceVerbose )
                            Trace.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]CrmUtil4SiteMap AddNewSubArea subAreaNd null: {0}", subAreaNd == null ),CRMTraceSwitch.Sw.Info);
                        GroupNd.InsertAfter(newSubArea, subAreaNd);
                    }
                }
                if (ret )
                {
                    DataXml                         =   _metadata.InnerXml;
                    if ( CRMTraceSwitch.Sw.TraceVerbose )
                        Trace.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]CrmUtil4SiteMap AddNewSubArea DataXml: {0}", DataXml),CRMTraceSwitch.Sw.Info);
                    ImportExportData.DataXml        =   DataXml;
                    ret                             =   ImportExportData.Import(wrapper,publish);
                }
                if ( !ret )
                    _errMsg                         =   ImportExportData.strErr;
            }
			catch (Exception ex)
			{
                if ( CRMTraceSwitch.Sw.TraceError )
                    Trace.WriteLine( string.Format(CultureInfo.InvariantCulture,"[E]CrmUtil4SiteMap AddNewSubArea ex: {0}",ex),CRMTraceSwitch.Sw.Info);
                throw;
			}
             if ( CRMTraceSwitch.Sw.TraceVerbose )
                Trace.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]CrmUtil4SiteMap AddNewSubArea END ret: {0}", ret),CRMTraceSwitch.Sw.Info);
            return ret;
        }

        /// <summary>
        /// Do a one shoot export/ ReOrder SubArea / import operation on CRM
        /// </summary>
        public bool ReOrderSubArea(string firstSubAreaId,string nextSubAreaId,bool publish)
        {
            if ( CRMTraceSwitch.Sw.TraceVerbose )
                Trace.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]CrmUtil4SiteMap ReOrderSubArea BEG firstSubAreaId: {0}, nextSubAreaId: {1}", 
                    firstSubAreaId,nextSubAreaId),CRMTraceSwitch.Sw.Info);
            bool ret                                =   false;
            try
            {
                ImportExportXml ImportExportData    =   new ImportExportXml(ImportExportType.sitemap);
                ret                                 =   ImportExportData.Export(wrapper);
                if ( ret )
                {
                    DataXml                         =   ImportExportData.DataXml;
                    Metadata                        =   new XmlDocument();
                    _metadata.LoadXml(DataXml);
                    string path                     =   string.Format("//SiteMap/SiteMap/Area/Group/SubArea[@Id='{0}']",firstSubAreaId);
                    XmlNode firstSubAreaNd          =   _metadata.SelectSingleNode(path);
                    if ( CRMTraceSwitch.Sw.TraceVerbose )
                        Trace.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]CrmUtil4SiteMap ReOrderSubArea firstSubAreaNd null: {0}", firstSubAreaNd == null ),CRMTraceSwitch.Sw.Info);
                    path                            =   string.Format("//SiteMap/SiteMap/Area/Group/SubArea[@Id='{0}']",nextSubAreaId);
                    XmlNode nextSubAreaNd           =   _metadata.SelectSingleNode(path);
                    if ( CRMTraceSwitch.Sw.TraceVerbose )
                        Trace.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]CrmUtil4SiteMap ReOrderSubArea nextSubAreaNd null: {0}", nextSubAreaNd == null ),CRMTraceSwitch.Sw.Info);
                    nextSubAreaNd.ParentNode.RemoveChild(nextSubAreaNd);
                    firstSubAreaNd.ParentNode.InsertAfter(nextSubAreaNd,firstSubAreaNd);
                }
                if (ret )
                {
                    DataXml                         =   _metadata.InnerXml;
                    if ( CRMTraceSwitch.Sw.TraceVerbose )
                        Trace.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]CrmUtil4SiteMap ReOrderSubArea DataXml: {0}", DataXml),CRMTraceSwitch.Sw.Info);
                    ImportExportData.DataXml        =   DataXml;
                    ret                             =   ImportExportData.Import(wrapper,publish);
                }
                if ( !ret )
                    _errMsg                         =   ImportExportData.strErr;
            }
			catch (Exception ex)
			{
                if ( CRMTraceSwitch.Sw.TraceError )
                    Trace.WriteLine( string.Format(CultureInfo.InvariantCulture,"[E]CrmUtil4SiteMap ReOrderSubArea ex: {0}",ex),CRMTraceSwitch.Sw.Info);
                throw;
			}
             if ( CRMTraceSwitch.Sw.TraceVerbose )
                Trace.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]CrmUtil4SiteMap ReOrderSubArea END ret: {0}", ret),CRMTraceSwitch.Sw.Info);
            return ret;
        }

        /// <summary>
        /// Do a one shoot export/ ReOrder Group / import operation on CRM
        /// </summary>
        public bool ReOrderGroup(string firstId,string nextId,bool publish)
        {
            if ( CRMTraceSwitch.Sw.TraceVerbose )
                Trace.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]CrmUtil4SiteMap ReOrderGroup BEG firstId: {0}, nextId: {1}", 
                    firstId,nextId),CRMTraceSwitch.Sw.Info);
            bool ret                                =   false;
            try
            {
                ImportExportXml ImportExportData    =   new ImportExportXml(ImportExportType.sitemap);
                ret                                 =   ImportExportData.Export(wrapper);
                if ( ret )
                {
                    DataXml                         =   ImportExportData.DataXml;
                    Metadata                        =   new XmlDocument();
                    _metadata.LoadXml(DataXml);
                    string path                     =   string.Format("//SiteMap/SiteMap/Area/Group[@Id='{0}']",firstId);
                    XmlNode firstNd                 =   _metadata.SelectSingleNode(path);
                    if ( CRMTraceSwitch.Sw.TraceVerbose )
                        Trace.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]CrmUtil4SiteMap ReOrderGroup firstNd null: {0}", firstNd == null ),CRMTraceSwitch.Sw.Info);
                    path                            =   string.Format("//SiteMap/SiteMap/Area/Group[@Id='{0}']",nextId);
                    XmlNode nextNd           =   _metadata.SelectSingleNode(path);
                    if ( CRMTraceSwitch.Sw.TraceVerbose )
                        Trace.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]CrmUtil4SiteMap ReOrderGroup nextNd null: {0}", nextNd == null ),CRMTraceSwitch.Sw.Info);
                    nextNd.ParentNode.RemoveChild(nextNd);
                    firstNd.ParentNode.InsertAfter(nextNd,firstNd);
                }
                if (ret )
                {
                    DataXml                         =   _metadata.InnerXml;
                    if ( CRMTraceSwitch.Sw.TraceVerbose )
                        Trace.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]CrmUtil4SiteMap ReOrderGroup DataXml: {0}", DataXml),CRMTraceSwitch.Sw.Info);
                    ImportExportData.DataXml        =   DataXml;
                    ret                             =   ImportExportData.Import(wrapper,publish);
                }
                if ( !ret )
                    _errMsg                         =   ImportExportData.strErr;
            }
			catch (Exception ex)
			{
                if ( CRMTraceSwitch.Sw.TraceError )
                    Trace.WriteLine( string.Format(CultureInfo.InvariantCulture,"[E]CrmUtil4SiteMap AddNewSubArea ex: {0}",ex),CRMTraceSwitch.Sw.Info);
                throw;
			}
             if ( CRMTraceSwitch.Sw.TraceVerbose )
                Trace.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]CrmUtil4SiteMap AddNewSubArea END ret: {0}", ret),CRMTraceSwitch.Sw.Info);
            return ret;
        }
        
        /// <summary>
        /// Do a one shoot export/ ReOrder Area / import operation on CRM
        /// </summary>
        public bool ReOrderArea(string firstId,string nextId,bool publish)
        {
            if ( CRMTraceSwitch.Sw.TraceVerbose )
                Trace.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]CrmUtil4SiteMap ReOrderArea BEG firstId: {0}, nextId: {1}", 
                    firstId,nextId),CRMTraceSwitch.Sw.Info);
            bool ret                                =   false;
            try
            {
                ImportExportXml ImportExportData    =   new ImportExportXml(ImportExportType.sitemap);
                ret                                 =   ImportExportData.Export(wrapper);
                if ( ret )
                {
                    DataXml                         =   ImportExportData.DataXml;
                    Metadata                        =   new XmlDocument();
                    _metadata.LoadXml(DataXml);
                    string path                     =   string.Format("//SiteMap/SiteMap/Area[@Id='{0}']",firstId);
                    XmlNode firstNd                 =   _metadata.SelectSingleNode(path);
                    if ( CRMTraceSwitch.Sw.TraceVerbose )
                        Trace.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]CrmUtil4SiteMap ReOrderGroup firstNd null: {0}", firstNd == null ),CRMTraceSwitch.Sw.Info);
                    path                            =   string.Format("//SiteMap/SiteMap/Area[@Id='{0}']",nextId);
                    XmlNode nextNd           =   _metadata.SelectSingleNode(path);
                    if ( CRMTraceSwitch.Sw.TraceVerbose )
                        Trace.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]CrmUtil4SiteMap ReOrderArea nextNd null: {0}", nextNd == null ),CRMTraceSwitch.Sw.Info);
                    nextNd.ParentNode.RemoveChild(nextNd);
                    firstNd.ParentNode.InsertAfter(nextNd,firstNd);
                }
                if (ret )
                {
                    DataXml                         =   _metadata.InnerXml;
                    if ( CRMTraceSwitch.Sw.TraceVerbose )
                        Trace.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]CrmUtil4SiteMap ReOrderArea DataXml: {0}", DataXml),CRMTraceSwitch.Sw.Info);
                    ImportExportData.DataXml        =   DataXml;
                    ret                             =   ImportExportData.Import(wrapper,publish);
                }
                if ( !ret )
                    _errMsg                         =   ImportExportData.strErr;
            }
			catch (Exception ex)
			{
                if ( CRMTraceSwitch.Sw.TraceError )
                    Trace.WriteLine( string.Format(CultureInfo.InvariantCulture,"[E]CrmUtil4SiteMap ReOrderArea ex: {0}",ex),CRMTraceSwitch.Sw.Info);
                throw;
			}
             if ( CRMTraceSwitch.Sw.TraceVerbose )
                Trace.WriteLine( string.Format(CultureInfo.InvariantCulture,"[V]CrmUtil4SiteMap ReOrderArea END ret: {0}", ret),CRMTraceSwitch.Sw.Info);
            return ret;
        }
        #endregion Ponctual operations
 
        #endregion public methods
    }
}